#if (FEATURE_MODE == 0)
/**
 @file sys_usw_srv6.c

 @date 2019-1-1

 @version v6.0


*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_error.h"
#include "ctc_nexthop.h"
#include "sys_usw_common.h"
#include "sys_usw_srv6.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_parser.h"
#include "sys_usw_acl_api.h"
#include "sys_usw_wb_common.h"
#include "drv_api.h"
#include "sys_usw_scl_api.h"
#include "sys_usw_register.h"
#include "sys_usw_l3if.h"



#define SYS_SRV6_DBG_OUT(level, FMT, ...) \
    do {\
        CTC_DEBUG_OUT(srv6, srv6, SRV6_SYS, level, FMT, ##__VA_ARGS__);  \
    } while (0)
#define SYS_SRV6_INIT_CHECK(lchip) \
    do { \
        LCHIP_CHECK(lchip); \
        if (NULL == p_usw_srv6_master[lchip]) \
        { \
            SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] Module not initialized \n");\
            return CTC_E_NOT_INIT;\
        } \
    } while (0)
#define SYS_SRV6_SID_OFFSET (40 + 8)  /*ipv6 header len + 8*/
#define SYS_SRV6_LOCK(lchip)  sal_mutex_lock(p_usw_srv6_master[lchip]->mutex)
#define SYS_SRV6_UNLOCK(lchip)  sal_mutex_unlock(p_usw_srv6_master[lchip]->mutex)

#define SYS_SRV6_MAX_SID_NUM 7    /*128b SID Number*/

#define SYS_SRV6_SRH_CHECK_DIS 7  /* Disable check SRH */

#define USID_MODE1_PREFIX_LEN 16
#define USID_MODE2_PREFIX_LEN 32
#define USID_MODE3_PREFIX_LEN 48
#define USID_USID_LEN         16
#define USID_RESERVED_LEN     16

#define GSID_PREFIX_LEN_16 16
#define GSID_PREFIX_LEN_32 32
#define GSID_PREFIX_LEN_48 48
#define GSID_PREFIX_LEN 64
#define GSID_GSID_LEN   32
#define GSID_RSV_ENTRY_FOR_PSP 3
#define GSID_RSV_ENTRY_FOR_SWAP_AND_POP 13
#define GSID_RSV_GROUP_SUB_ID 4

#define SYS_AT_SRV6_EDIT_BASE_SID     		  0         /* Normal SID Base */
#define SYS_AT_SRV6_EDIT_BASE_USID    		  32        /* USID Base */
#define SYS_AT_SRV6_EDIT_BASE_GSID    		  64        /* GSID Base */
#define SYS_AT_SRV6_EDIT_BASE_SID_AM_DE_MASQ  96       /* SID AM De-masquerading Base */
#define SYS_AT_SRV6_EDIT_BASE_DISABLE 		  0         /* Disable Base */

/* srhUpdDis, uspEn, pspEn, 0, 0 */
#define SYS_AT_SRV6_EDIT_BMP_POP   0
#define SYS_AT_SRV6_EDIT_BMP_SWAP  0b10000
#define SYS_AT_SRV6_EDIT_BMP_PSP   0b10100
#define SYS_AT_SRV6_EDIT_BMP_USP   0b11000

#define SYS_AT_SRV6_EDIT_RSV_LPORT_NUM   128

#define SYS_SID_MASK_LEN 80
#define SYS_SID_MASK_LEN_128 128

struct sys_srv6_master_s
{
    sal_mutex_t* mutex;
    uint32 fp_id_swap;
    uint32 fp_id_psp;
    uint32 fp_id_usp;
    uint32 fp_id_shift;
	uint32 fp_id_am_de_masq;/*de-masquerading */
    uint32 fp_id_gsid_swap;
    uint32 fp_id_gsid_pop;
    uint32 fp_id_gsid_psp;
    uint16 udf_idx_base;
    uint8 masklen[2];
    uint8 sid_format;
    uint8 rsv[3];
    uint32 ldp_base;/*AT*/
};
typedef struct sys_srv6_master_s sys_srv6_master_t;
sys_srv6_master_t* p_usw_srv6_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};

STATIC int32
_sys_usw_srv6_init_sredit(uint8 lchip, uint8 deinit)
{
    uint32 cmd = 0;
    uint8 i = 0;
    ctc_nh_fp_edit_t fp_edit;
    sys_nh_info_dsnh_t fp_info;
    ctc_nh_fp_field_t field_list[5];
    uint32 value;
    ds_t   ds;

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (deinit)
    {
        if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_NORMAL))
        {
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_swap);
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_psp);
			sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_am_de_masq);
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_usp);
        }
        if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_USID))
        {
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_shift);
        }
        if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_GSID))
        {
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_gsid_swap);
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_gsid_pop);
            sys_usw_nh_remove_fp(lchip, p_usw_srv6_master[lchip]->fp_id_gsid_psp);
        }

        for (i = 0; i < SYS_AT_SRV6_EDIT_RSV_LPORT_NUM; i++)
        {
            value = 0;
            cmd = DRV_IOW(DsEgressLogicDestPort_t, DsEgressLogicDestPort_outerEditPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_usw_srv6_master[lchip]->ldp_base + i, cmd, &value));
            cmd = DRV_IOW(DsEgressLogicDestPort_t, DsEgressLogicDestPort_outerEditPtrType_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_usw_srv6_master[lchip]->ldp_base + i, cmd, &value));
            cmd = DRV_IOW(DsEgressLogicDestPort_t, DsEgressLogicDestPort_editPtrMode_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_usw_srv6_master[lchip]->ldp_base + i, cmd, &value));
        }

        p_usw_srv6_master[lchip]->fp_id_swap = 0;
        p_usw_srv6_master[lchip]->fp_id_psp = 0;
		p_usw_srv6_master[lchip]->fp_id_am_de_masq = 0;
        p_usw_srv6_master[lchip]->fp_id_usp = 0;
        p_usw_srv6_master[lchip]->fp_id_shift = 0;
        p_usw_srv6_master[lchip]->fp_id_gsid_swap = 0;
        p_usw_srv6_master[lchip]->fp_id_gsid_pop = 0;
        p_usw_srv6_master[lchip]->fp_id_gsid_psp = 0;
        CTC_ERROR_RETURN(sys_usw_nh_free(lchip, SYS_API_NH_LOGIC_DEST_PORT, SYS_AT_SRV6_EDIT_RSV_LPORT_NUM, p_usw_srv6_master[lchip]->ldp_base));

        return CTC_E_NONE;
    }

    /*init*/
    /* Normal SID */
    if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_NORMAL))
    {
        /* 1. init flex edit for none psp*/
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        fp_edit.p_field_list = field_list;
        fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
        fp_edit.offset = 0; /*ipda offset from l3 offset*/
        fp_edit.offset_type = CTC_PKT_OFFSET_L3;
        fp_edit.field_cnt = 5;
        for (i = 0; i < 4; i++)
        {
            field_list[i].offset = i*32 + 24*8;/*ipda bits offset from l3 offset*/
            field_list[i].len = 32;
            field_list[i].data.type = CTC_NH_FP_DATA_PACKET;
            field_list[i].data.len = 32;
            field_list[i].data.shift = i*32;
        }
        field_list[4].offset = (40+3)*8;/*SL bits offset from l3 offset*/
        field_list[4].len = 8;
        field_list[4].zone_op = CTC_NH_FP_OP_SUB;
        field_list[4].data.type = CTC_NH_FP_DATA_RAW;
        field_list[4].data.len = 8;
        field_list[4].data.value = 1;/*SL--*/

        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_swap = fp_edit.fp_id;
        /* 2. init flex edit for psp*/
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        fp_edit.p_field_list = field_list;
        fp_edit.edit_type = CTC_NH_FP_EDIT_DEL;
        fp_edit.offset = 40;/*SRH offset from l3 offset*/
        fp_edit.offset_type = CTC_PKT_OFFSET_L3;
        fp_edit.len_from_data = 1;
        fp_edit.length.type = CTC_NH_FP_DATA_FLEX_LEN;

        fp_edit.offset_ext = 0;
        fp_edit.offset_type_ext = CTC_PKT_OFFSET_L3;
        fp_edit.field_cnt = 5;
        for (i = 0; i < 4; i++)
        {
            field_list[i].offset = i*32 + 24*8;/*ipda bits offset from l3 offset*/
            field_list[i].len = 32;
            field_list[i].data.type = CTC_NH_FP_DATA_PACKET;
            field_list[i].data.len = 32;
            field_list[i].data.shift = i*32;
        }
        field_list[4].offset = 6*8;/*next header bits offset from l3 offset*/
        field_list[4].len = 8;
        field_list[4].data.type = CTC_NH_FP_DATA_L3_PROTOCOL;/*replace next header*/
        field_list[4].data.len = 8;
        field_list[4].data.shift = 0;

        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_psp = fp_edit.fp_id;
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            sal_memset(&fp_info, 0, sizeof(sys_nh_info_dsnh_t));
            CTC_ERROR_RETURN(sys_usw_nh_get_fp_info(lchip, fp_edit.fp_id, &fp_info));
            cmd = DRV_IOW(IpeUserIdSrCtl_t, IpeUserIdSrCtl_srPspEditPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &fp_info.l3_edit_ptr));
        }

        /* 3. init flex edit for usp */
        if (DRV_FROM_AT(lchip)) /* USP: Only for arctic */
        {
            sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
            sal_memset(&field_list, 0, sizeof(field_list));
            fp_edit.p_field_list = field_list;
            fp_edit.edit_type = CTC_NH_FP_EDIT_DEL;
            fp_edit.offset = 40;/*SRH offset from l3 offset*/
            fp_edit.offset_type = CTC_PKT_OFFSET_L3;
            fp_edit.len_from_data = 1;
            fp_edit.length.type = CTC_NH_FP_DATA_FLEX_LEN;

            fp_edit.offset_ext = 0;
            fp_edit.offset_type_ext = CTC_PKT_OFFSET_L3;
            fp_edit.field_cnt = 1;
            field_list[0].offset = 6*8;/*next header bits offset from l3 offset*/
            field_list[0].len = 8;
            field_list[0].data.type = CTC_NH_FP_DATA_L3_PROTOCOL;/*replace next header*/
            field_list[0].data.len = 8;
            field_list[0].data.shift = 0;

            CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
            p_usw_srv6_master[lchip]->fp_id_usp = fp_edit.fp_id;
        }

		/* 4. init flex edit for am de-masquerading */
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        fp_edit.p_field_list = field_list;
        fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
        fp_edit.offset = 0; /*ipda offset from l3 offset*/
        fp_edit.offset_type = CTC_PKT_OFFSET_L3;
        fp_edit.field_cnt = 4;
        for (i = 0; i < 4; i++)
        {
            field_list[i].offset = i*32 + 24*8;/*ipda bits offset from l3 offset*/
            field_list[i].len = 32;
            field_list[i].data.type = CTC_NH_FP_DATA_PACKET;
            field_list[i].data.len = 32;
            field_list[i].data.shift = i*32;
        }
        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_am_de_masq = fp_edit.fp_id;
    }

    if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_USID))
    {
        /* uSID */
        /* 5. init flex edit for usid shift */
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        switch (p_usw_srv6_master[lchip]->masklen[1])
        {
            case (USID_MODE1_PREFIX_LEN + USID_USID_LEN):
                fp_edit.p_field_list = field_list;
                fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
                fp_edit.offset = 26;/*ipda offset from l3 offset*/
                fp_edit.offset_type = CTC_PKT_OFFSET_L3;
                fp_edit.len = 12;

                fp_edit.offset_ext = 0;
                fp_edit.offset_type_ext = CTC_PKT_OFFSET_L3;
                fp_edit.field_cnt = 4;
                for (i = 0; i < 3; i++)
                {
                    field_list[i].offset = i*32;/*move to*/
                    field_list[i].len = 32;
                    field_list[i].data.type = CTC_NH_FP_DATA_PACKET;
                    field_list[i].data.len = 32;
                    field_list[i].data.shift = i*32; /*select from origin data, origin data offset come from ipe*/
                }

                field_list[3].offset = i*32;/*clear*/
                field_list[3].len = 16;
                field_list[3].data.type = CTC_NH_FP_DATA_RAW;
                field_list[3].data.len = 16;
                field_list[3].data.shift = 0;
                break;
            case (USID_MODE2_PREFIX_LEN + USID_USID_LEN):
                fp_edit.p_field_list = field_list;
                fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
                fp_edit.offset = 28;/*ipda offset from l3 offset*/
                fp_edit.offset_type = CTC_PKT_OFFSET_L3;
                fp_edit.len = 12;

                fp_edit.offset_ext = 0;
                fp_edit.offset_type_ext = CTC_PKT_OFFSET_L3;
                fp_edit.field_cnt = 4;
                for (i = 0; i < 3; i++)
                {
                    field_list[i].offset = i*32;/*move to*/
                    field_list[i].len = 32;
                    field_list[i].data.type = CTC_NH_FP_DATA_PACKET;
                    field_list[i].data.len = 32;
                    field_list[i].data.shift = i*32; /*select from origin data, origin data offset come from ipe*/
                }

                field_list[3].offset = (i - 1)*32 + 16;/*clear*/
                field_list[3].len = 16;
                field_list[3].data.type = CTC_NH_FP_DATA_RAW;
                field_list[3].data.len = 16;
                field_list[3].data.shift = 0;
                break;
            case (USID_MODE3_PREFIX_LEN + USID_USID_LEN):
                fp_edit.p_field_list = field_list;
                fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
                fp_edit.offset = 30;/*ipda offset from l3 offset*/
                fp_edit.offset_type = CTC_PKT_OFFSET_L3;
                fp_edit.len = 12;
                fp_edit.field_cnt = 3;

                for (i = 0; i < 2; i++)
                {
                    field_list[i].offset = i*32;/*move to*/
                    field_list[i].len = 32;
                    field_list[i].data.type = CTC_NH_FP_DATA_PACKET;
                    field_list[i].data.len = 32;
                    field_list[i].data.shift = i*32; /*select from origin data, origin data offset come from ipe*/
                }

                field_list[2].offset = i*32;/*clear*/
                field_list[2].len = 16;
                field_list[2].data.type = CTC_NH_FP_DATA_RAW;
                field_list[2].data.len = 16;
                field_list[2].data.shift = 0;
                break;
            default:
                break;

        }
        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_shift = fp_edit.fp_id;
    }
    else if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_GSID))
    {
        /* gSID */
        /* 6. init flex edit for gsid swap */
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        fp_edit.p_field_list = field_list;
        fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
        fp_edit.offset = 24; /*ipda offset from l3 offset*/
        fp_edit.offset_type = CTC_PKT_OFFSET_L3;
        fp_edit.field_cnt = 3;

        field_list[0].offset = p_usw_srv6_master[lchip]->masklen[0]-GSID_GSID_LEN+16;  /*2*32 ipda bits offset from l3 offset*/
        field_list[0].len = 16;
        field_list[0].data_op = CTC_NH_FP_OP_ADD;
        field_list[0].data.type = CTC_NH_FP_DATA_PACKET;
        field_list[0].data.len = 32;
        field_list[0].data.shift = 0;
        field_list[0].data_r.len = 4;
        field_list[0].result_shift = 0;

        field_list[1].offset = p_usw_srv6_master[lchip]->masklen[0]-GSID_GSID_LEN;  /*2*32 ipda bits offset from l3 offset*/
        field_list[1].len = 16;
        field_list[1].data_op = CTC_NH_FP_OP_ADD;
        field_list[1].data.type = CTC_NH_FP_DATA_PACKET;
        field_list[1].data.len = 32;
        field_list[1].data.shift = 0;
        field_list[1].data_r.len = 4;
        field_list[1].result_shift = 16;

        field_list[2].offset = 3*32;/*SI bits offset from l3 offset*/
        field_list[2].len = 32;
        field_list[2].zone_op = CTC_NH_FP_OP_SUB;
        field_list[2].data.type = CTC_NH_FP_DATA_RAW;
        field_list[2].data.len = 32;
        field_list[2].data.mask = 0x3;            /* SI Behand Gsid : 0xc0000000; End of IPDA : 0x3 */
        field_list[2].data.value = 0x1;/*SI--*/   /* SI Behand Gsid : 0x40000000; End of IPDA : 0x1 */

        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_gsid_swap = fp_edit.fp_id;

        /* 7. init flex edit for gsid pop */
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        fp_edit.p_field_list = field_list;
        fp_edit.edit_type = CTC_NH_FP_EDIT_REP;
        fp_edit.offset = 24; /*ipda offset from l3 offset*/
        fp_edit.offset_type = CTC_PKT_OFFSET_L3;
        fp_edit.field_cnt = 4;

        field_list[0].offset = p_usw_srv6_master[lchip]->masklen[0]-GSID_GSID_LEN+16;/*ipda bits offset from l3 offset*/
        field_list[0].len = 16;
        field_list[0].data_op = CTC_NH_FP_OP_ADD;
        field_list[0].data.type = CTC_NH_FP_DATA_PACKET;
        field_list[0].data.len = 32;
        field_list[0].data.shift = 0;
        field_list[0].data_r.len = 4;
        field_list[0].result_shift = 0;

        field_list[1].offset = p_usw_srv6_master[lchip]->masklen[0]-GSID_GSID_LEN;/*ipda bits offset from l3 offset*/
        field_list[1].len = 16;
        field_list[1].data_op = CTC_NH_FP_OP_ADD;
        field_list[1].data.type = CTC_NH_FP_DATA_PACKET;
        field_list[1].data.len = 32;
        field_list[1].data.shift = 0;
        field_list[1].data_r.len = 4;
        field_list[1].result_shift = 16;

        field_list[2].offset = 3*32;/*SI bits offset from l3 offset*/
        field_list[2].len = 32;
        field_list[2].data.type = CTC_NH_FP_DATA_RAW;
        field_list[2].data.len = 32;
        field_list[2].data.value = 0x3;/*SI=3*/ /* SI Behand Gsid : 0xc0000000; End of IPDA : 0x3 */

        field_list[3].offset = 4*32 + 3*8;/*SL bits offset from l3 offset*/
        field_list[3].len = 8;
        field_list[3].zone_op = CTC_NH_FP_OP_SUB;
        field_list[3].data.type = CTC_NH_FP_DATA_RAW;
        field_list[3].data.len = 8;
        field_list[3].data.value = 1;    /*SL--*/

        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_gsid_pop = fp_edit.fp_id;

        /* 8. init flex edit for gsid psp */
        sal_memset(&fp_edit, 0, sizeof(ctc_nh_fp_edit_t));
        sal_memset(&field_list, 0, sizeof(field_list));
        fp_edit.p_field_list = field_list;
        fp_edit.edit_type = CTC_NH_FP_EDIT_DEL;
        fp_edit.offset = 40;/*SRH offset from l3 offset*/
        fp_edit.offset_type = CTC_PKT_OFFSET_L3;
        fp_edit.len_from_data = 1;
        fp_edit.length.type = CTC_NH_FP_DATA_FLEX_LEN;

        fp_edit.offset_ext = 6;
        fp_edit.offset_type_ext = CTC_PKT_OFFSET_L3;
        fp_edit.field_cnt = 4;

        field_list[0].offset = p_usw_srv6_master[lchip]->masklen[0]-GSID_GSID_LEN + 18*8 + 16;/*gsid(low 16bits) of ipda bits offset from l3 offset*/
        field_list[0].len = 16;
        field_list[0].data_op = CTC_NH_FP_OP_ADD;
        field_list[0].data.type = CTC_NH_FP_DATA_PACKET;
        field_list[0].data.len = 32;
        field_list[0].data.shift = 0;
        field_list[0].data_r.len = 4;
        field_list[0].result_shift = 0;

        field_list[1].offset = p_usw_srv6_master[lchip]->masklen[0]-GSID_GSID_LEN + 18*8;/*gsid(high 16bits) of ipda bits offset from l3 offset*/
        field_list[1].len = 16;
        field_list[1].data_op = CTC_NH_FP_OP_ADD;
        field_list[1].data.type = CTC_NH_FP_DATA_PACKET;
        field_list[1].data.len = 32;
        field_list[1].data.shift = 0;
        field_list[1].data_r.len = 4;
        field_list[1].result_shift = 16;

        field_list[2].offset = 8*32;/*SI bits offset from l3 offset*/ /* SI Behand Gsid : 3*32 + 18*8; End of IPDA : 8*32 */
        field_list[2].len = 16;
        field_list[2].zone_op = CTC_NH_FP_OP_SUB;
        field_list[2].data.type = CTC_NH_FP_DATA_RAW;
        field_list[2].data.len = 16;
        field_list[2].data.mask = 0x3;               /* SI Behand Gsid : 0xc000; End of IPDA : 0x3 */
        field_list[2].data.value = 0x1;/*SI--*/      /* SI Behand Gsid : 0x4000; End of IPDA : 0x1 */

        field_list[3].offset = 0;/*next header bits offset from l3 offset*/
        field_list[3].len = 8;
        field_list[3].data.type = CTC_NH_FP_DATA_L3_PROTOCOL;/*replace next header*/
        field_list[3].data.len = 8;
        field_list[3].data.shift = 0;

        CTC_ERROR_RETURN(sys_usw_nh_add_fp(lchip, &fp_edit, 1));
        p_usw_srv6_master[lchip]->fp_id_gsid_psp = fp_edit.fp_id;
    }

    if (DRV_FROM_AT(lchip))
    {
        uint32 flex_edit[][2] = {
            {p_usw_srv6_master[lchip]->fp_id_swap, (SYS_AT_SRV6_EDIT_BASE_SID + SYS_AT_SRV6_EDIT_BMP_POP)},
            {p_usw_srv6_master[lchip]->fp_id_psp, (SYS_AT_SRV6_EDIT_BASE_SID + SYS_AT_SRV6_EDIT_BMP_PSP)},
            {p_usw_srv6_master[lchip]->fp_id_usp, (SYS_AT_SRV6_EDIT_BASE_SID + SYS_AT_SRV6_EDIT_BMP_USP)},
            {p_usw_srv6_master[lchip]->fp_id_am_de_masq, (SYS_AT_SRV6_EDIT_BASE_SID_AM_DE_MASQ + SYS_AT_SRV6_EDIT_BMP_POP)},
            {p_usw_srv6_master[lchip]->fp_id_shift, (SYS_AT_SRV6_EDIT_BASE_USID + SYS_AT_SRV6_EDIT_BMP_SWAP)},
            {p_usw_srv6_master[lchip]->fp_id_gsid_swap, (SYS_AT_SRV6_EDIT_BASE_GSID + SYS_AT_SRV6_EDIT_BMP_SWAP)},
            {p_usw_srv6_master[lchip]->fp_id_gsid_pop, (SYS_AT_SRV6_EDIT_BASE_GSID + SYS_AT_SRV6_EDIT_BMP_POP)},
            {p_usw_srv6_master[lchip]->fp_id_gsid_psp, (SYS_AT_SRV6_EDIT_BASE_GSID + SYS_AT_SRV6_EDIT_BMP_PSP)}
        };

        sal_memset(ds, 0, sizeof(ds_t));
        SetDsEgressLogicDestPort(V, outerEditPtrType_f, ds, 1);
        SetDsEgressLogicDestPort(V, editPtrMode_f, ds, 1);
        CTC_ERROR_RETURN(sys_usw_nh_alloc(lchip, SYS_API_NH_LOGIC_DEST_PORT, SYS_AT_SRV6_EDIT_RSV_LPORT_NUM, &p_usw_srv6_master[lchip]->ldp_base));
        for (i = 0; i < sizeof(flex_edit)/(sizeof(uint32)*2); i++) /* 9 flexeditptr */
        {
            if(0 == flex_edit[i][0])
            {
                continue;
            }
            CTC_ERROR_RETURN(sys_usw_nh_get_fp_info(lchip, flex_edit[i][0], &fp_info));
            SetDsEgressLogicDestPort(V, outerEditPtr_f, ds, fp_info.l3_edit_ptr);
            cmd = DRV_IOW(DsEgressLogicDestPort_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, flex_edit[i][1] + p_usw_srv6_master[lchip]->ldp_base, cmd, ds));
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_srv6_init_udf(uint8 lchip, uint8 deinit)
{
    uint32 udf_idx_base = p_usw_srv6_master[lchip]->udf_idx_base;
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if (DRV_FROM_AT(lchip))
    {
        return CTC_E_NONE;
    }
    CTC_ERROR_RETURN(sys_usw_acl_resv_udf_for_srv6(lchip,
              &udf_idx_base, p_usw_srv6_master[lchip]->sid_format, p_usw_srv6_master[lchip]->masklen[1], p_usw_srv6_master[lchip]->masklen[0], deinit));
    p_usw_srv6_master[lchip]->udf_idx_base = udf_idx_base;
    return CTC_E_NONE;
}

int32
_sys_usw_srv6_init_scl(uint8 lchip, uint8 deinit)
{
    ctc_scl_group_info_t group;
    uint32 group_id = 0;
    uint8 scl_id = 0;

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&group, 0, sizeof(ctc_scl_group_info_t));
    group.type = CTC_SCL_GROUP_TYPE_NONE;
    for (scl_id = 0; scl_id < 4; scl_id++)
    {
        group_id = SYS_SCL_ENCODE_INNER_GRP_ID(CTC_FEATURE_SRV6, scl_id, 0, 0, 0);
        group.priority = scl_id;
        if (deinit)
        {
            /*do nothing*/
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_scl_create_group(lchip, group_id, &group, 1));
        }
    }

    /* create gsid reserved scl group */
    group_id = SYS_SCL_ENCODE_INNER_GRP_ID(CTC_FEATURE_SRV6, GSID_RSV_GROUP_SUB_ID, 0, 0, 0);
    group.type = CTC_SCL_GROUP_TYPE_NONE;
    group.priority = 2;
    CTC_ERROR_RETURN(sys_usw_scl_create_group(lchip, group_id, &group, 1));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_srv6_init_gsid_scl_tcam(uint8 lchip, uint8 deinit)
{
    ctc_scl_group_info_t group;
    ctc_scl_entry_t scl_entry;
    ctc_field_key_t field_key;
    ctc_acl_udf_t udf_data;
    ctc_acl_udf_t udf_mask;
    sys_nh_info_dsnh_t fp_info;
    sys_scl_srv6_t srv6;
    ctc_scl_field_action_t field_action;
    uint32 group_id = 0;
    uint8 i = 0;
    uint8 sl = 0;
    uint8 si = 0;
    uint8 hdr_len = 0;

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&field_key, 0, sizeof(ctc_field_key_t));
    sal_memset(&udf_data, 0, sizeof(ctc_acl_udf_t));
    sal_memset(&udf_mask, 0, sizeof(ctc_acl_udf_t));
    sal_memset(&fp_info, 0, sizeof(sys_nh_info_dsnh_t));
    sal_memset(&srv6, 0, sizeof(sys_scl_srv6_t));
    sal_memset(&field_action, 0, sizeof(ctc_scl_field_action_t));

    group_id = SYS_SCL_ENCODE_INNER_GRP_ID(CTC_FEATURE_SRV6, GSID_RSV_GROUP_SUB_ID, 0, 0, 0);

    if (deinit)
    {
        CTC_ERROR_RETURN(sys_usw_scl_uninstall_group(lchip, group_id, 1));
        CTC_ERROR_RETURN(sys_usw_scl_remove_all_entry(lchip, group_id, 1));
        return CTC_E_NONE;
    }

    /* reserved for gsid pop */
    for (i = 0; i < GSID_RSV_ENTRY_FOR_SWAP_AND_POP; i++)
    {
        /* Add entry and build key */
        sal_memset(&field_key, 0, sizeof(ctc_field_key_t));
        sal_memset(&udf_data, 0, sizeof(ctc_acl_udf_t));
        sal_memset(&udf_mask, 0, sizeof(ctc_acl_udf_t));
        sal_memset(&scl_entry, 0, sizeof(ctc_scl_entry_t));
        sl = i / 4;
        si = i - ((i / 4) * 4);
        if ((!si && !sl) || (si == 1 && sl == 0))
        {
            continue;
        }
        if (!si && sl)  /* si == 0, sl != 0 */
        {
            CTC_ERROR_RETURN(sys_usw_nh_get_fp_info(lchip, p_usw_srv6_master[lchip]->fp_id_gsid_pop, &fp_info));
        }
        else if (si)  /* si != 0 */
        {
            CTC_ERROR_RETURN(sys_usw_nh_get_fp_info(lchip, p_usw_srv6_master[lchip]->fp_id_gsid_swap, &fp_info));
        }

        scl_entry.action_type = SYS_SCL_ACTION_INGRESS;
        scl_entry.mode = 1;
        scl_entry.key_type = SYS_SCL_KEY_TCAM_UDF;
        CTC_ERROR_RETURN(sys_usw_scl_add_entry(lchip, group_id, &scl_entry, 1));
        /* Build Key */
        udf_data.udf_id = SYS_ACL_UDE_RSV_ID(SYS_ACL_UDF_RSV_SRV6);
        udf_data.udf[1] = sl;              /* SL */
        udf_mask.udf[1] = 0xFF;
        udf_data.udf[5] = si;              /* SI */ /* SI Behand Gsid : udf[6] = si << 6; End of IPDA : udf[5] = si */
        udf_mask.udf[5] = 0x03;                     /* SI Behand Gsid : udf[6] = 0xC0; End of IPDA : udf[5] = 0x03 */
        field_key.type = CTC_FIELD_KEY_UDF;
        field_key.ext_data = &udf_data;
        field_key.ext_mask = &udf_mask;
        CTC_ERROR_RETURN(sys_usw_scl_add_key_field(lchip, scl_entry.entry_id, &field_key));
        /* Build Action */
        srv6.edit_ptr = fp_info.l3_edit_ptr;
        srv6.is_gsid_rsv = 1;
        srv6.is_user_def = 1;
        srv6.udf_idx = p_usw_srv6_master[lchip]->udf_idx_base + SYS_SRV6_MAX_SID_NUM + i;      /* udf_idx and user_def_offset need match to each other */
        srv6.user_def_offset = 48 + sl*16 + si*4 - 4;                                              /* IPDA offset from l3offset */
        field_action.type = SYS_SCL_FIELD_ACTION_TYPE_SRV6;
        field_action.ext_data = &srv6;
        CTC_ERROR_RETURN(sys_usw_scl_add_action_field(lchip, scl_entry.entry_id, &field_action));
    }

    /* reserved for gsid psp */
    for (i = 0; i < GSID_RSV_ENTRY_FOR_PSP; i++)
    {
        /* Add entry and build key */
        sal_memset(&field_key, 0, sizeof(ctc_field_key_t));
        sal_memset(&udf_data, 0, sizeof(ctc_acl_udf_t));
        sal_memset(&udf_mask, 0, sizeof(ctc_acl_udf_t));
        sal_memset(&scl_entry, 0, sizeof(ctc_scl_entry_t));
        sl = 0;
        si = 1;
        hdr_len = (i + 1) * 2;
        CTC_ERROR_RETURN(sys_usw_nh_get_fp_info(lchip, p_usw_srv6_master[lchip]->fp_id_gsid_psp, &fp_info));
        scl_entry.action_type = SYS_SCL_ACTION_INGRESS;
        scl_entry.mode = 1;
        scl_entry.key_type = SYS_SCL_KEY_TCAM_UDF;
        CTC_ERROR_RETURN(sys_usw_scl_add_entry(lchip, group_id, &scl_entry, 1));
        /* Build Key */
        udf_data.udf_id = SYS_ACL_UDE_RSV_ID(SYS_ACL_UDF_RSV_SRV6);
        udf_data.udf[1] = sl;              /* SL */
        udf_mask.udf[1] = 0xFF;
        udf_data.udf[3] = hdr_len;         /* Hdr Ext Len */
        udf_mask.udf[3] = 0xFF;
        udf_data.udf[5] = si;              /* SI */ /* SI Behand Gsid : udf[6] = si << 6; End of IPDA : udf[5] = si */
        udf_mask.udf[5] = 0x03;                     /* SI Behand Gsid : udf[6] = 0xC0; End of IPDA : udf[5] = 0x03 */
        field_key.type = CTC_FIELD_KEY_UDF;
        field_key.ext_data = &udf_data;
        field_key.ext_mask = &udf_mask;
        CTC_ERROR_RETURN(sys_usw_scl_add_key_field(lchip, scl_entry.entry_id, &field_key));
        /* Build Action */
        srv6.edit_ptr = fp_info.l3_edit_ptr;
        srv6.is_gsid_rsv = 1;
        srv6.is_user_def = 1;
        srv6.udf_idx = p_usw_srv6_master[lchip]->udf_idx_base + SYS_SRV6_MAX_SID_NUM + 1;      /* udf_idx and user_def_offset need match to each other */
        srv6.user_def_offset = 48 + sl*16 + si*4 - 4;                                              /* IPDA offset from l3offset */
        srv6.psp_en = 1;
        srv6.hdr_len = (hdr_len + 1) << 3;                                                     /* (SRH Header + SID List) * 8 */
        field_action.type = SYS_SCL_FIELD_ACTION_TYPE_SRV6;
        field_action.ext_data = &srv6;
        CTC_ERROR_RETURN(sys_usw_scl_add_action_field(lchip, scl_entry.entry_id, &field_action));
    }

    /* install group */
    sal_memset(&group, 0, sizeof(group));
    group.priority = 2;
    CTC_ERROR_RETURN(sys_usw_scl_install_group(lchip, group_id, &group, 1));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_srv6_init_register(uint8 lchip)
{
    uint32 cmd = 0;
    ds1_t   ds;
    uint32 value = 0;
    EpeHdrAdjustXCtl_m epehdr_xctl;

    if (DRV_FROM_AT(lchip))
    {
        uint32 mask[4] = {0};
        sal_memset(mask, 0, sizeof(mask));

        /* IpePreLookupCtl */
        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOR(IpePreLookupCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        SetIpePreLookupCtl(V, sr6ExtType_f, ds, SYS_PARSER_EXT_TYPE_SRV6);
        SetIpePreLookupCtl(V, sr6Type_f, ds, 4);
        cmd = DRV_IOW(IpePreLookupCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

        /* ParserIpCtl */
        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOR(ParserIpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        SetParserIpCtl(V, ipv6ExtHdr0ProtocolEn_f, ds, 1);
        SetParserIpCtl(V, ipv6ExtHdr0Protocol_f, ds, 43);
        SetParserIpCtl(V, ipv6ExtHdr0Type_f, ds, SYS_PARSER_L3_EXT_TYPE_SRV6);
        SetParserIpCtl(V, gL3ExtType_6_typeValue_f, ds, SYS_PARSER_EXT_TYPE_SRV6);
        cmd = DRV_IOW(ParserIpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

        /* IpeUserIdSrCtl */
        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOR(IpeUserIdSrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        SetIpeUserIdSrCtl(V, ipNxtHdr_f, ds, 43);
        SetIpeUserIdSrCtl(V, extType_f, ds, SYS_PARSER_EXT_TYPE_SRV6);
        SetIpeUserIdSrCtl(V, routingType_f, ds, 4);
        SetIpeUserIdSrCtl(V, flexEditPtrMode_f, ds, 0);

        SetIpeUserIdSrCtl(V, gAluNxtHdr_2_value_f, ds, 143); /* ETH */
        SetIpeUserIdSrCtl(V, gAluNxtHdr_2_mode_f, ds, 0);
        SetIpeUserIdSrCtl(V, gAluNxtHdr_2_escape_f, ds, 1);

        SetIpeUserIdSrCtl(V, gAluNxtHdr_1_value_f, ds, 4);  /* IPv4 */
        SetIpeUserIdSrCtl(V, gAluNxtHdr_1_mode_f, ds, 0);
        SetIpeUserIdSrCtl(V, gAluNxtHdr_1_escape_f, ds, 1);

        SetIpeUserIdSrCtl(V, gAluNxtHdr_3_value_f, ds, 41);   /* IPv6 */
        SetIpeUserIdSrCtl(V, gAluNxtHdr_3_mode_f, ds, 0);
        SetIpeUserIdSrCtl(V, gAluNxtHdr_3_escape_f, ds, 1);

        SetIpeUserIdSrCtl(V, gEscape_1_discardType_f, ds, 50);
        SetIpeUserIdSrCtl(V, gEscape_1_exceptionSubIndex_f, ds, 1);

        SetIpeUserIdSrCtl(V, segLeftEscape_f, ds, 2);
        SetIpeUserIdSrCtl(V, gEscape_2_discardType_f, ds, 51);
        SetIpeUserIdSrCtl(V, gEscape_2_exceptionSubIndex_f, ds, 2);

        SetIpeUserIdSrCtl(V, srhEscape_f, ds, 3);
        SetIpeUserIdSrCtl(V, gEscape_3_discardType_f, ds, 52);
        SetIpeUserIdSrCtl(V, gEscape_3_exceptionSubIndex_f, ds, 3);

        SetIpeUserIdSrCtl(V, srhLenEscape_f, ds, 4);
        SetIpeUserIdSrCtl(V, gEscape_4_discardType_f, ds, 53);
        SetIpeUserIdSrCtl(V, gEscape_4_exceptionSubIndex_f, ds, 4);

        SetIpeUserIdSrCtl(V, exceptionIndex_f, ds, 3);

        SetIpeUserIdSrCtl(V, gEdit_0_validEn_f, ds, 255);                      /* SID */
        SetIpeUserIdSrCtl(V, gEdit_0_value_f, ds, p_usw_srv6_master[lchip]->ldp_base+ SYS_AT_SRV6_EDIT_BASE_SID);

        SetIpeUserIdSrCtl(V, gEdit_1_validEn_f, ds, 255);                      /* uSID */
        SetIpeUserIdSrCtl(V, gEdit_1_value_f, ds, p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_USID);

        SetIpeUserIdSrCtl(V, gEdit_2_validEn_f, ds, 255);                      /* gSID */
        SetIpeUserIdSrCtl(V, gEdit_2_value_f, ds, p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_GSID);

        SetIpeUserIdSrCtl(V, gEdit_3_validEn_f, ds, 0);                        /* disable */
        SetIpeUserIdSrCtl(V, gEdit_3_value_f, ds, SYS_AT_SRV6_EDIT_BASE_DISABLE);

		SetIpeUserIdSrCtl(V, gEdit_4_validEn_f, ds, 255);                        /* SID_END_AM_DE_MASQ */
        SetIpeUserIdSrCtl(V, gEdit_4_value_f, ds, p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_SID_AM_DE_MASQ);

        SetIpeUserIdSrCtl(V, xSidXiMode_f, ds, 1);
        SetIpeUserIdSrCtl(V, srhSlLimit_f, ds, 7);

//        SetIpeUserIdSrCtl(V, uSidShiftMode_f, ds, 1);/*AT_TODO*/

        SetIpeUserIdSrCtl(V, gDecapNextHeader_0_value_f, ds, 59);
        SetIpeUserIdSrCtl(V, gDecapNextHeader_1_value_f, ds, 4);         /* IPv4 */
        SetIpeUserIdSrCtl(V, gDecapNextHeader_2_value_f, ds, 41);        /* IPv6 */
        SetIpeUserIdSrCtl(V, gDecapNextHeader_3_value_f, ds, 143);       /* ETH */
        SetIpeUserIdSrCtl(V, xSidSel_f, ds, 1);                          /* SI = ipDa(1,0) */
        SetIpeUserIdSrCtl(V, xSidXiMode_f, ds, 1);                       /* SI is 2 bits*/

        SetIpeUserIdSrCtl(A, gSidValue_0_value_f, ds, mask);
        SetIpeUserIdSrCtl(A, gSidValue_1_value_f, ds, mask);
        mask[0] = 0x000000FF;
        mask[1] = 0x00000000;
        mask[2] = 0x00000000;
        mask[3] = 0x00000000;
        SetIpeUserIdSrCtl(A, gSidMask_1_value_f, ds, mask); /* gsid */

        cmd = DRV_IOW(IpeUserIdSrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

        /* IpeLookupCtl */
        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOR(IpeLookupCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

        SetIpeLookupCtl(V, gNxtSid_1_mode_f, ds, 1); /* Normal sid */
        SetIpeLookupCtl(V, gNxtSid_3_mode_f, ds, 5); /* gsid */

        cmd = DRV_IOW(IpeLookupCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

        /* EpeHdrAdjustXCtl */
        cmd = DRV_IOR(EpeHdrAdjustXCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epehdr_xctl));
        SetEpeHdrAdjustXCtl(V, extType0_f, &epehdr_xctl, SYS_PARSER_EXT_TYPE_SRV6); /*srv6 exttype*/
        cmd = DRV_IOW(EpeHdrAdjustXCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epehdr_xctl));
    }
    else
    {
        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOR(ParserIpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        SetParserIpCtl(V, ipv6ExtHdr0ProtocolEn_f, ds, 1);
        SetParserIpCtl(V, ipv6ExtHdr0Protocol_f, ds, 43);
        SetParserIpCtl(V, ipv6ExtHdr0Type_f, ds, SYS_PARSER_L3_EXT_TYPE_SRV6);
        cmd = DRV_IOW(ParserIpCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

        cmd = DRV_IOR(ParserUdfLookupCtl_t, ParserUdfLookupCtl_udfL3ExtTypeEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        CTC_BIT_SET(value, SYS_PARSER_L3_EXT_TYPE_SRV6);
        cmd = DRV_IOW(ParserUdfLookupCtl_t, ParserUdfLookupCtl_udfL3ExtTypeEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

        sal_memset(ds, 0, sizeof(ds_t));
        cmd = DRV_IOR(IpeUserIdSrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        SetIpeUserIdSrCtl(V, rhExtType_f, ds, SYS_PARSER_L3_EXT_TYPE_SRV6);
        SetIpeUserIdSrCtl(V, srType_f, ds, 4);
        SetIpeUserIdSrCtl(V, srEnhEth_f, ds, 143);
        SetIpeUserIdSrCtl(V, srEnhIp6_f, ds, 41);
        SetIpeUserIdSrCtl(V, srEnhIp4_f, ds, 4);
        SetIpeUserIdSrCtl(V, srSlLimit_f, ds, SYS_SRV6_MAX_SID_NUM);
        SetIpeUserIdSrCtl(V, srUdfHitIndexBase_f, ds, p_usw_srv6_master[lchip]->udf_idx_base);
        SetIpeUserIdSrCtl(V, uSidUdfHitIndexBase_f, ds,
            CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_NORMAL) ?
            (p_usw_srv6_master[lchip]->udf_idx_base + SYS_SRV6_MAX_SID_NUM + 1) : (p_usw_srv6_master[lchip]->udf_idx_base));
        SetIpeUserIdSrCtl(V, srCheckFailMode_f, ds, 0);
        SetIpeUserIdSrCtl(V, srSlLimitMode_f, ds, 0);
        SetIpeUserIdSrCtl(V, srLookupMode_f, ds, CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_USID) ? 1 : 0);
        cmd = DRV_IOW(IpeUserIdSrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    }
    /* Disable parser check of the packet longer than asic ability */
    /*sdk support 7 sids, so inner packet include ip\ipv4\ipv6\ethoam.. all maybe length error*/
    sal_memset(ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(ParserL3Ctl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    SetParserL3Ctl(V, layer3ParserLengthErrorIgnore_f, ds, 0xFFFF);
    cmd = DRV_IOW(ParserL3Ctl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    sal_memset(ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(ParserLayer4AppCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    SetParserLayer4AppCtl(V, layer4ExtParserLengthErrorIgnore_f, ds, 0xFFFF);
    cmd = DRV_IOW(ParserLayer4AppCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    sal_memset(ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(IpePreLookupCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    SetIpePreLookupCtl(V, parserLengthErrorMode_f, ds, 2);
    cmd = DRV_IOW(IpePreLookupCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    sal_memset(ds, 0, sizeof(ds_t));
    cmd = DRV_IOR(IpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    SetIpeAclQosCtl(V, fatalExceptionBypassRedirect_f, ds, 0);
    cmd = DRV_IOW(IpeAclQosCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_srv6_param_check(uint8 lchip, ctc_srv6_sid_t* my_sid)
{
    uint32  mac[2] = {0};
    if (my_sid->type >= CTC_SRV6_TYPE_MAX)
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] Invalid srv6 type!\n");
        return CTC_E_INVALID_PARAM;
    }
    if (my_sid->edit_type >= CTC_SRV6_EDIT_TYPE_MAX)
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] Invalid srv6 edit type!\n");
        return CTC_E_INVALID_PARAM;
    }
    if (( my_sid->scl_id > 3)
        || (( my_sid->scl_id > 1) && !CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USE_FLEX))
        || (( my_sid->scl_id <= 1) && CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USE_FLEX)))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] Invalid scl id!\n");
        return CTC_E_INVALID_PARAM;
    }
    if (my_sid->fid > MCHIP_CAP(SYS_CAP_SPEC_MAX_FID))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] FID is out of range!\n");
        return CTC_E_BADID;
    }
    if (my_sid->vrf_id > MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] VRFID is out of range!\n");
        return CTC_E_BADID;
    }
    if ( my_sid->logic_port >= MCHIP_CAP(SYS_CAP_MAX_LOGIC_PORT) )
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] Logic port is out of range!\n");
        return CTC_E_INVALID_PORT;
    }
    if (my_sid->inner_pkt_type >= PKT_TYPE_RESERVED)
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] Illegal inner packet type!\n");
        return CTC_E_INVALID_PARAM;
    }
    if ((!((CTC_SRV6_TYPE_E == my_sid->type) || (CTC_SRV6_TYPE_X == my_sid->type) || (CTC_SRV6_TYPE_T == my_sid->type)
         || (CTC_SRV6_TYPE_ENCAPS == my_sid->type) || (CTC_SRV6_TYPE_AM == my_sid->type) || (CTC_SRV6_TYPE_NONE == my_sid->type)))
        && CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_PSP_EN))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] No need PSP!\n");
        return CTC_E_INVALID_PARAM;
    }
    if (((CTC_SRV6_TYPE_DT == my_sid->type && !sal_memcmp(mac, my_sid->route_mac , sizeof(mac_addr_t))) ||
        (CTC_SRV6_TYPE_DT != my_sid->type && sal_memcmp(mac, my_sid->route_mac , sizeof(mac_addr_t)))) && CTC_SRV6_TYPE_NONE != my_sid->type)
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [SRV6] End Behavior Type Error!\n");
        return CTC_E_INVALID_PARAM;
    }
    return CTC_E_NONE;
}

STATIC uint8
_sys_usw_srv6_mapping_scl_key_type(uint8 lchip, ctc_srv6_sid_t* my_sid)
{
    uint8 key_type = 0;
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USE_FLEX))
    {
        ctc_global_scl_property_t scl_property;
        sal_memset(&scl_property, 0, sizeof(ctc_global_scl_property_t));
        scl_property.dir = CTC_INGRESS;
        scl_property.lkup_level = my_sid->scl_id;
        CTC_ERROR_RETURN(sys_usw_global_ctl_get(lchip, CTC_GLOBAL_SCL_PROPERTY, (void*)&scl_property));
        if (scl_property.ipv6_single_mode == 2)
        {
            key_type = SYS_SCL_KEY_TCAM_IPV6_SINGLE;
        }
        else
        {
            key_type = SYS_SCL_KEY_TCAM_IPV6;
        }
    }
    else
    {
        if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_USID) &&
            p_usw_srv6_master[lchip]->masklen[1] == (USID_MODE1_PREFIX_LEN + USID_USID_LEN))
        {
            key_type = (my_sid->scl_id == 0)? SYS_SCL_KEY_HASH_IPV6_DA : SYS_SCL_KEY_HASH_IPV4_DA;
        }
        else
        {
            key_type = SYS_SCL_KEY_HASH_IPV6_DA;
        }
    }
    return key_type;
}

STATIC int32
_sys_usw_srv6_build_key(uint8 lchip, uint32 entry_id, uint8 key_type, ctc_srv6_sid_t* my_sid)
{
    ctc_field_key_t field_key;
    ipv6_addr_t sid_mask;
    ipv6_addr_t sid_mask1;
    uint8 mask_len = 0;

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&field_key, 0, sizeof(ctc_field_key_t));
    sal_memset(&sid_mask, 0, sizeof(sid_mask));

    if (my_sid->masklen)
    {
        mask_len = my_sid->masklen;
    }
    else
    {
        mask_len = p_usw_srv6_master[lchip]->masklen[my_sid->scl_id];
    }

    if (key_type == SYS_SCL_KEY_HASH_IPV4_DA)
    {
        field_key.type = CTC_FIELD_KEY_L3_TYPE;
        field_key.data = CTC_PARSER_L3_TYPE_IPV6;/*L3TYPE_IPV6*/
        CTC_ERROR_RETURN(sys_usw_scl_add_key_field(lchip, entry_id, &field_key));

        IPV6_LEN_TO_MASK(sid_mask, mask_len);
        SYS_USW_REVERT_IP6(sid_mask1, sid_mask);
        field_key.type = CTC_FIELD_KEY_IP_DA;
        field_key.data = my_sid->sid[0] & sid_mask1[0];
    }
    else if (key_type == SYS_SCL_KEY_HASH_IPV6_DA)
    {
        field_key.type = CTC_FIELD_KEY_IPV6_DA;
        IPV6_LEN_TO_MASK(sid_mask, mask_len);
        SYS_USW_REVERT_IP6(sid_mask1, sid_mask);
        my_sid->sid[0] &= sid_mask1[0];
        my_sid->sid[1] &= sid_mask1[1];
        my_sid->sid[2] &= sid_mask1[2];
        my_sid->sid[3] &= sid_mask1[3];
        field_key.ext_data = my_sid->sid;
    }
    else if ((key_type == SYS_SCL_KEY_TCAM_IPV6)||(key_type == SYS_SCL_KEY_TCAM_IPV6_SINGLE))
    {
        field_key.type = CTC_FIELD_KEY_IPV6_DA;
        field_key.ext_data = my_sid->sid;
        IPV6_LEN_TO_MASK(sid_mask, my_sid->masklen);
        SYS_USW_REVERT_IP6(sid_mask1, sid_mask);
        field_key.ext_mask = sid_mask1;
    }
    CTC_ERROR_RETURN(sys_usw_scl_add_key_field(lchip, entry_id, &field_key));

    if (!CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USE_FLEX))
    {
        field_key.type = CTC_FIELD_KEY_HASH_VALID;
        CTC_ERROR_RETURN(sys_usw_scl_add_key_field(lchip, entry_id, &field_key));
    }

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_srv6_construct_key(uint8 lchip, ctc_srv6_sid_t* my_sid, sys_scl_lkup_key_t* p_lkup_key)
{
    ctc_field_key_t field_key;
    ipv6_addr_t sid_mask;
    ipv6_addr_t sid_mask1;
    uint8 mask_len = 0;

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&field_key, 0, sizeof(ctc_field_key_t));
    sal_memset(&sid_mask, 0, sizeof(sid_mask));
    p_lkup_key->key_type = _sys_usw_srv6_mapping_scl_key_type(lchip, my_sid);
    p_lkup_key->action_type = SYS_SCL_ACTION_INGRESS;
    p_lkup_key->group_id = SYS_SCL_ENCODE_INNER_GRP_ID(CTC_FEATURE_SRV6, my_sid->scl_id, 0, 0, 0);
    p_lkup_key->group_priority = my_sid->scl_id;

    if (my_sid->masklen)
    {
        mask_len = my_sid->masklen;
    }
    else
    {
        mask_len = p_usw_srv6_master[lchip]->masklen[my_sid->scl_id];
    }

    if (p_lkup_key->key_type == SYS_SCL_KEY_HASH_IPV4_DA)
    {
        field_key.type = CTC_FIELD_KEY_L3_TYPE;
        field_key.data = CTC_PARSER_L3_TYPE_IPV6;/*L3TYPE_IPV6*/
        CTC_ERROR_RETURN(sys_usw_scl_construct_lkup_key(lchip, &field_key, p_lkup_key));

        IPV6_LEN_TO_MASK(sid_mask, mask_len);
        SYS_USW_REVERT_IP6(sid_mask1, sid_mask);
        field_key.type = CTC_FIELD_KEY_IP_DA;
        field_key.data = my_sid->sid[0] & sid_mask1[0];
    }
    else if (p_lkup_key->key_type == SYS_SCL_KEY_HASH_IPV6_DA)
    {
        field_key.type = CTC_FIELD_KEY_IPV6_DA;
        IPV6_LEN_TO_MASK(sid_mask, mask_len);
        SYS_USW_REVERT_IP6(sid_mask1, sid_mask);
        my_sid->sid[0] &= sid_mask1[0];
        my_sid->sid[1] &= sid_mask1[1];
        my_sid->sid[2] &= sid_mask1[2];
        my_sid->sid[3] &= sid_mask1[3];
        field_key.ext_data = my_sid->sid;
    }
    else if ((p_lkup_key->key_type == SYS_SCL_KEY_TCAM_IPV6)||(p_lkup_key->key_type == SYS_SCL_KEY_TCAM_IPV6_SINGLE))
    {
        field_key.type = CTC_FIELD_KEY_IPV6_DA;
        field_key.ext_data = my_sid->sid;
        IPV6_LEN_TO_MASK(sid_mask, my_sid->masklen);
        SYS_USW_REVERT_IP6(sid_mask1, sid_mask);
        field_key.ext_mask = sid_mask1;
    }
    CTC_ERROR_RETURN(sys_usw_scl_construct_lkup_key(lchip, &field_key, p_lkup_key));

    if (!CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USE_FLEX))
    {
        field_key.type = CTC_FIELD_KEY_HASH_VALID;
        CTC_ERROR_RETURN(sys_usw_scl_construct_lkup_key(lchip, &field_key, p_lkup_key));
    }
    field_key.type = SYS_SCL_FIELD_KEY_COMMON;
    CTC_ERROR_RETURN(sys_usw_scl_construct_lkup_key(lchip, &field_key, p_lkup_key));

    CTC_ERROR_RETURN(sys_usw_scl_get_entry_id_by_lkup_key(lchip, p_lkup_key));

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_srv6_build_action(uint8 lchip, uint32 entry_id, ctc_srv6_sid_t* my_sid, uint8 is_update)
{
    int32 ret = CTC_E_NONE;
    ctc_scl_field_action_t field_action;
    ctc_scl_logic_port_t scl_logic_port;
    sys_scl_srv6_t srv6;
    sys_nh_info_dsnh_t fp_info;
    uint32 fp_id = 0;
	uint16 route_mac_index = 0;
    uint16 router_mac_profile = 0;
    mac_addr_t mac;
    mac_addr_t mac_addrs;
    sys_scl_srv6_t srv6_db[CTC_SRV6_TYPE_MAX] =
    {/*op_type, sid_swap, strip_type, second_parser, inner_lookup, lookup_en, pkt_type, is_decap*/
        {1, 0, 0, 0, 0, 0, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_NONE   */
        {1, 1, 0, 0, 0, 1, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_E      */
        {1, 1, 0, 0, 0, 0, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_X      */
        {1, 1, 0, 0, 0, 1, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_T      */
        {2, 0, 3, 1, 0, 0, PKT_TYPE_ETH, 1},         /*CTC_SRV6_TYPE_DX2    */
        {2, 0, 3, 0, 1, 0, PKT_TYPE_ETH, 1},         /*CTC_SRV6_TYPE_DT2U   */
        {2, 0, 3, 0, 1, 0, PKT_TYPE_ETH, 1},         /*CTC_SRV6_TYPE_DT2M   */
        {3, 0, 3, 1, 0, 0, PKT_TYPE_IPV6, 1},        /*CTC_SRV6_TYPE_DX6    */
        {4, 0, 3, 1, 0, 0, PKT_TYPE_IPV4, 1},        /*CTC_SRV6_TYPE_DX4    */
        {3, 0, 3, 0, 1, 0, PKT_TYPE_IPV6, 1},        /*CTC_SRV6_TYPE_DT6    */
        {4, 0, 3, 0, 1, 0, PKT_TYPE_IPV4, 1},        /*CTC_SRV6_TYPE_DT4    */
        {5, 0, 3, 0, 1, 0, PKT_TYPE_IP, 1},          /*CTC_SRV6_TYPE_DT46   */
        {1, 0, 3, 0, 0, 0, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_INSERT */
        {1, 1, 3, 0, 0, 0, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_ENCAPS */
        {1, 0, 0, 0, 0, 1, PKT_TYPE_RESERVED, 0},    /*CTC_SRV6_TYPE_AM */
		{0, 0, 3, 0, 1, 0, PKT_TYPE_ETH, 1}          /*CTC_SRV6_TYPE_DT */
    };
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&field_action, 0, sizeof(ctc_scl_field_action_t));
    sal_memset(&scl_logic_port, 0, sizeof(ctc_scl_logic_port_t));
    sal_memset(&srv6, 0, sizeof(sys_scl_srv6_t));
    sal_memset(&mac, 0, sizeof(mac_addr_t));
    sal_memset(&mac_addrs, 0, sizeof(mac_addr_t));

    if (is_update)
    {
    	field_action.type = SYS_SCL_FIELD_ACTION_TYPE_SRV6;
	    field_action.ext_data = &srv6;
	    CTC_ERROR_RETURN(sys_usw_scl_get_action_field(lchip, entry_id, &field_action));
        router_mac_profile = srv6.router_mac_profile;
        CTC_ERROR_RETURN(sys_usw_l3if_get_inner_router_mac(lchip, router_mac_profile, &mac_addrs));
        if (router_mac_profile)
        {
            CTC_ERROR_RETURN(sys_usw_l3if_unbinding_inner_router_mac(lchip, router_mac_profile));
		}
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_PENDING;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_0);
    }

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "sid type = %d, flag = 0x%x, scl_id = %d, nh_id = %d, fid = %d\n",
                                                                                         my_sid->type, my_sid->flag, my_sid->scl_id,  my_sid->nh_id, my_sid->fid);
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "vrf_id = %d, logic_port = %d, stats_id = %d, policer_id = %d \n",
                                                                                         my_sid->vrf_id, my_sid->logic_port, my_sid->stats_id, my_sid->policer_id);

    /* SRV6 Flag */
    sal_memcpy(&srv6, &srv6_db[my_sid->type], sizeof(srv6));
    srv6.psp_en = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_PSP_EN))? 1 : 0;
    srv6.usp_en = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USP_EN)) ? 1 : 0;
    srv6.usd_en = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USD_EN)) ? 1 : 0;
    srv6.ttl_chk = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_TTL_CHECK))? 1 : 0;
    srv6.use_outer_ttl = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USE_OUTER_TTL))? 1 : 0;
    srv6.coc_flavor = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_COC_EN))? 1 : 0;

    if (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_DECAP_EN) || (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USD_EN)))
    {
        uint8 op_type[PKT_TYPE_RESERVED] = {2, 4, 0, 3, 0, 5, 0};/* PKT_TYPE_ETH, PKT_TYPE_IPV4, N/A, PKT_TYPE_IPV6, N/A, PKT_TYPE_IP, N/A */

        srv6.op_type = op_type[my_sid->inner_pkt_type];
        srv6.inner_lookup = (my_sid->nh_id && !my_sid->fid) ? 0 : 1;   //For CTC_SRV6_TYPE_DT2M
        srv6.second_parser = my_sid->nh_id ? 1 : 0;
        srv6.pkt_type = my_sid->inner_pkt_type;
        srv6.strip_type = 3;
        srv6.is_decap = 1;     /*For Arctic*/
    }


    /* Behavior Type */
    if (CTC_SRV6_TYPE_NONE == my_sid->type)
    {
        if (!CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_DECAP_EN) && !(CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_USD_EN)))
        {
            switch (my_sid->edit_type)
            {
                case CTC_SRV6_EDIT_TYPE_0:
                    fp_id = p_usw_srv6_master[lchip]->fp_id_swap;
                    srv6.sid_swap = 1;
                    srv6.lookup_en = 1;
                    break;
                case CTC_SRV6_EDIT_TYPE_1:
                    fp_id = p_usw_srv6_master[lchip]->fp_id_swap;
                    srv6.is_user_def = 1;
                    srv6.user_def_offset = 48;
                    srv6.edit_offset_cal = 0;
                    srv6.edit_type = 0;     /*For Arctic*/
                    break;
                case CTC_SRV6_EDIT_TYPE_2:
                    fp_id = p_usw_srv6_master[lchip]->fp_id_am_de_masq;
                    srv6.is_user_def = 1;
                    srv6.user_def_offset = 48;
                    srv6.edit_offset_cal = 1;
                    srv6.edit_type = 4;     /*For Arctic*/
                    break;
                default:
                    break;
            }
        }
        srv6.fid = (my_sid->fid && my_sid->nh_id) ? my_sid->fid : 0;
    }
    else
    {
        if (CTC_SRV6_TYPE_AM == my_sid->type && (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_DE_MASQ)))
	    {
	    	fp_id = p_usw_srv6_master[lchip]->fp_id_am_de_masq;
            srv6.user_def_offset = 48;
            srv6.is_user_def = 1;
            srv6.edit_type = 4;
	    	srv6.edit_offset_cal = 1;
	    }
        else if (CTC_SRV6_TYPE_AM == my_sid->type)
        {
            fp_id = p_usw_srv6_master[lchip]->fp_id_swap;
            srv6.user_def_offset = 48;
            srv6.is_user_def = 1;
            srv6.edit_type = 0;
	    	srv6.edit_offset_cal = 0;
        }
        else if ((CTC_SRV6_TYPE_E == my_sid->type) || (CTC_SRV6_TYPE_X == my_sid->type) || (CTC_SRV6_TYPE_T == my_sid->type)
             || (CTC_SRV6_TYPE_ENCAPS == my_sid->type))
        {
            fp_id = p_usw_srv6_master[lchip]->fp_id_swap;
        }
        else if(CTC_SRV6_TYPE_DT2M == my_sid->type)
        {
            srv6.fid = my_sid->fid;
        }
    }

    /* SID Format */
    if (CTC_SRV6_SID_FORMAT_USID == my_sid->format)
    {
        fp_id = p_usw_srv6_master[lchip]->fp_id_shift;
        srv6.is_usid = 1;
        srv6.is_user_def = DRV_FROM_AT(lchip) ? 0 : 1;
        srv6.user_def_offset = ((USID_MODE1_PREFIX_LEN + USID_USID_LEN) == p_usw_srv6_master[lchip]->masklen[1]) ? 28 :
                           (((USID_MODE2_PREFIX_LEN + USID_USID_LEN) == p_usw_srv6_master[lchip]->masklen[1]) ? 30 : 32);/*IPDA offset from l3offset*/
    }
    else if (CTC_SRV6_SID_FORMAT_GSID == my_sid->format)
    {
        srv6.is_gsid = 1;
    }

    if (fp_id && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        CTC_ERROR_GOTO(sys_usw_nh_get_fp_info(lchip, fp_id, &fp_info), ret, error_1);
        srv6.edit_ptr = fp_info.l3_edit_ptr;
    }

	if (sal_memcmp(&mac, &(my_sid->route_mac), sizeof(mac_addr_t)))
    {
        CTC_ERROR_GOTO(sys_usw_l3if_binding_inner_router_mac(lchip, &(my_sid->route_mac), &route_mac_index), ret, error_1);
        srv6.router_mac_profile = route_mac_index;
    }

    srv6.op_type = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_LEGALITY_CHECK_DIS)) ? SYS_SRV6_SRH_CHECK_DIS : srv6.op_type;

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "op_type = %d, sid_swap = %d, strip_type = %d, second_parser = %d \n",
                                                                                      srv6.op_type, srv6.sid_swap, srv6.strip_type, srv6.second_parser);
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "inner_lookup = %d, lookup_en = %d, pkt_type = %d, psp_en = %d, usp_en = %d, usd_en = %d, edit_ptr = %d, is_decap = %d \n",
                                                                                      srv6.inner_lookup, srv6.lookup_en, srv6.pkt_type, srv6.psp_en, srv6.usp_en, srv6.usd_en, srv6.edit_ptr, srv6.is_decap);
    field_action.type = SYS_SCL_FIELD_ACTION_TYPE_SRV6;
    field_action.ext_data = &srv6;
    CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);

    if (my_sid->stats_id)
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_STATS;
        field_action.data0 = my_sid->stats_id;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_DENY_LEARNING))
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_DENY_LEARNING;
        field_action.data0 = 1;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if(CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_ACL_LKUP_BY_OUTER_HEAD))
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_FLOW_LKUP_BY_OUTER_HEAD;
        field_action.data0 = 1;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if ((CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_LOGIC_PORT_TYPE)) || my_sid->logic_port)
    {
        scl_logic_port.logic_port =  my_sid->logic_port & 0xFFFF;
        scl_logic_port.logic_port_type = (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_LOGIC_PORT_TYPE))? 1 : 0;
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_LOGIC_PORT;
        field_action.ext_data = &scl_logic_port;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if (my_sid->nh_id)
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_DENY_BRIDGE;
        field_action.data0 = 1;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_DENY_ROUTE;
        field_action.data0 = 1;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);

        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_REDIRECT;
        field_action.data0 = my_sid->nh_id;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if (my_sid->fid && CTC_SRV6_TYPE_DT2M != my_sid->type && !my_sid->nh_id)
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_FID;
        field_action.data0 = my_sid->fid;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if(my_sid->vrf_id)
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_VRFID;
        field_action.data0 = my_sid->vrf_id;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if (my_sid->policer_id)
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_POLICER_ID;
        field_action.data0 = my_sid->policer_id;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_COPY_TO_CPU))
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_COPY_TO_CPU;
        field_action.data0 = 1;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    if (CTC_FLAG_ISSET(my_sid->flag, CTC_SRV6_SID_FLAG_DISCARD))
    {
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_DISCARD;
        field_action.data0 = 1;
        CTC_ERROR_GOTO(sys_usw_scl_add_action_field(lchip, entry_id, &field_action), ret, error_2);
    }
    return CTC_E_NONE;

error_2:
    if (route_mac_index)
    {
        sys_usw_l3if_unbinding_inner_router_mac(lchip, route_mac_index);
    }
error_1:
    field_action.type = CTC_SCL_FIELD_ACTION_TYPE_PENDING;
    sys_usw_scl_remove_action_field(lchip, entry_id, &field_action);
error_0:
    if (is_update && router_mac_profile)
    {
        sys_usw_l3if_binding_inner_router_mac(lchip, &mac_addrs, &route_mac_index);
    }
    return ret;
}

int32
sys_usw_srv6_set_global_cfg(uint8 lchip, ctc_srv6_global_cfg_t* p_global_cfg, uint8 masklen, uint8 scl_id)
{
    uint32 mask0[4] = {0};
    uint32 mask1[4] = {0};
    ds1_t ds;
    uint32 cmd = 0;
    uint8 mask_len0 = 0;
    uint8 mask_len1 = 0;
    ctc_srv6_global_cfg_t srv6_glb_cfg;
    sal_memset(ds, 0, sizeof(ds1_t));

    SYS_SRV6_INIT_CHECK(lchip);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MASTER, 1);

    if (NULL == p_global_cfg)
    {
        if (((CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_GSID)) && (0 == scl_id))
            && ((masklen<(GSID_PREFIX_LEN_16 + GSID_GSID_LEN)) 
            || (masklen>(GSID_PREFIX_LEN + GSID_GSID_LEN))
            || (0 != (masklen %16))))
        {
            return CTC_E_INVALID_PARAM;
        }
        p_usw_srv6_master[lchip]->masklen[scl_id] = masklen;
        mask_len0 = p_usw_srv6_master[lchip]->masklen[0];
        mask_len1 = p_usw_srv6_master[lchip]->masklen[1];
        sal_memset(&srv6_glb_cfg, 0, sizeof(srv6_glb_cfg));
        srv6_glb_cfg.sid_format_bmp = p_usw_srv6_master[lchip]->sid_format;
        CTC_ERROR_RETURN(sys_usw_srv6_set_sid_format(lchip, &srv6_glb_cfg));
        p_global_cfg = &srv6_glb_cfg;
        goto proc;
    }
    else
    {
        if (CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_USID))
        {
            p_usw_srv6_master[lchip]->masklen[0] = USID_MODE3_PREFIX_LEN + USID_USID_LEN + USID_RESERVED_LEN;
            p_usw_srv6_master[lchip]->masklen[1] = USID_MODE3_PREFIX_LEN + USID_USID_LEN;
        }
        else if (CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_GSID))
        {
            p_usw_srv6_master[lchip]->masklen[0] = GSID_PREFIX_LEN + GSID_GSID_LEN;
            p_usw_srv6_master[lchip]->masklen[1] = GSID_PREFIX_LEN + GSID_GSID_LEN;
        }
        else         /* CTC_SRV6_SID_FORMAT_NORMAL */
        {
            p_usw_srv6_master[lchip]->masklen[0] = SYS_SID_MASK_LEN_128;
            p_usw_srv6_master[lchip]->masklen[1] = SYS_SID_MASK_LEN;
        }

        mask_len0 = p_usw_srv6_master[lchip]->masklen[0];
        mask_len1 = p_usw_srv6_master[lchip]->masklen[1];
    }
    /* Read Registers */
    cmd = DRV_IOR(UserIdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    /* Write Register */
    SetUserIdCtl(V, sr6Mode_f, ds, 0);
    SetUserIdCtl(V, sr6ForceIpv4_f, ds, 0);
    sal_memset(mask1, 0, sizeof(mask1));
    SetUserIdCtl(A, g_0_sr6Wildcard_f, ds, mask1);
	SetUserIdCtl(A, g_1_sr6Wildcard_f, ds, mask1);
    SetUserIdCtl(A, g_1_sr6WildcardShort_f, ds, mask1);

    sal_memset(mask0, 0xff, (sizeof(uint32) * 4));
    sal_memset(mask1, 0xff, (sizeof(uint32) * 4));

    SYS_SID_MASK(mask0, mask_len0);
    SYS_SID_MASK(mask1, mask_len1);

    if ((mask_len1 <= CTC_IPV4_ADDR_LEN_IN_BIT) && CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_USID))
    {
        SetUserIdCtl(V, sr6ForceIpv4_f, ds, 0x2);/*SCL hash1 use ipv4 key, 32bits key*/
        SetUserIdCtl(V, sr6Mode_f, ds, 0x6);

        SetUserIdCtl(A, g_0_sr6Wildcard_f, ds, mask0);            /* SCL Hash0 ipv6 key mask */ /* SCL0 used for swap 128bits sid */
        SetUserIdCtl(V, g_1_sr6WildcardShort_f, ds, mask1[3]);    /* SCL Hash1 ipv4 key mask */ /* SCL1 used for shift usid */
    }
    else if (CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_USID))
    {
        SetUserIdCtl(A, g_0_sr6Wildcard_f, ds, mask0);         /* SCL Hash0 ipv6 key mask */ /* SCL0 used for swap 128bits sid */
        SetUserIdCtl(A, g_1_sr6Wildcard_f, ds, mask1);         /* SCL Hash1 ipv4 key mask */ /* SCL1 used for shift usid */
    }
    else if ((mask_len1 <= CTC_IPV4_ADDR_LEN_IN_BIT) && !CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_USID))
    {
        SetUserIdCtl(V, g_0_sr6WildcardShort_f, ds, mask0[3]);
        SetUserIdCtl(V, g_1_sr6WildcardShort_f, ds, mask1[3]);
    }
    else
    {
        SetUserIdCtl(A, g_0_sr6Wildcard_f, ds, mask0);
        SetUserIdCtl(A, g_1_sr6Wildcard_f, ds, mask1);
    }

    SetUserIdCtl(V, gSr6PrefixMode_0_value_f, ds, 0);
    SetUserIdCtl(V, gSr6PrefixMode_1_value_f, ds, 0);

    p_usw_srv6_master[lchip]->sid_format = p_global_cfg->sid_format_bmp;

    cmd = DRV_IOW(UserIdCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

proc:
    if (DRV_FROM_AT(lchip))
    {
        ds_t ds2;
        uint8 mask_len = 0;
        uint32 mask[4] = {0};

        sal_memset(ds, 0, sizeof(ds1_t));
        sal_memset(ds2, 0, sizeof(ds_t));

        cmd = DRV_IOR(IpeUserIdSrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        cmd = DRV_IOR(IpeLookupCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds2));

        /* usid */
        if (CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_USID))
        {
            mask_len = p_usw_srv6_master[lchip]->masklen[1] - USID_USID_LEN;
            if (USID_MODE1_PREFIX_LEN >= mask_len)  /* prefix 16bits */
            {
                mask[0] = 0x00000000;mask[1] = 0x00000000;mask[2] = 0xFFFF0000;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_2_mode_f, ds2, 2);
            }
            else if (USID_MODE2_PREFIX_LEN >= mask_len) /* prefix 32bits */
            {
                mask[0] = 0x00000000;mask[1] = 0x00000000;mask[2] = 0x0000FFFF;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_2_mode_f, ds2, 3);

            }
            else if (USID_MODE3_PREFIX_LEN >= mask_len) /* prefix 48bits */
            {
                mask[0] = 0x00000000;mask[1] = 0xFFFF0000;mask[2] = 0x00000000;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_2_mode_f, ds2, 4);
            }
        }
        else if (CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_GSID))
        {
            mask_len = p_usw_srv6_master[lchip]->masklen[0] - GSID_GSID_LEN;
            if (GSID_PREFIX_LEN_16 >= mask_len)  /* prefix 16bits */
            {
                mask[0] = 0x00000000;mask[1] = 0x00000000;mask[2] = 0xFFFF0000;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_3_mode_f, ds2, 2);
            }
            else if (GSID_PREFIX_LEN_32 >= mask_len) /* prefix 32bits */
            {
                mask[0] = 0x00000000;mask[1] = 0x00000000;mask[2] = 0x0000FFFF;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_3_mode_f, ds2, 3);

            }
            else if (GSID_PREFIX_LEN_48 >= mask_len) /* prefix 48bits */
            {
                mask[0] = 0x00000000;mask[1] = 0xFFFF0000;mask[2] = 0x00000000;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_3_mode_f, ds2, 4);
            }
            else if (GSID_PREFIX_LEN >= mask_len) /* prefix 64bits */
            {
                mask[0] = 0x00000000;mask[1] = 0x0000FFFF;mask[2] = 0x00000000;mask[3] = 0x00000000;
                SetIpeUserIdSrCtl(A, gSidMask_0_value_f, ds, mask);
                SetIpeLookupCtl(V, gNxtSid_3_mode_f, ds2, 5);
            }
        }
        

        cmd = DRV_IOW(IpeUserIdSrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
        cmd = DRV_IOW(IpeLookupCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds2));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_srv6_wb_init(uint8 lchip)
{
   ctc_wb_appid_t  appid;
   sal_memset(&appid,0,sizeof(appid));

   appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MASTER) ;
   appid.entry_num = SYS_WB_FEATURE_MASTER_NUM;
   appid.entry_size  = sizeof(sys_wb_srv6_master_t);
   appid.rt_en = 0;
   ctc_wb_add_appid(lchip, &appid);

   return CTC_E_NONE;
}

STATIC int32
_sys_usw_srv6_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param)
{
    SYS_SRV6_INIT_CHECK(lchip);

    SYS_SRV6_LOCK(lchip);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "# SRv6");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","fp_id_swap", p_usw_srv6_master[lchip]->fp_id_swap);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_psp", p_usw_srv6_master[lchip]->fp_id_psp);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_usp", p_usw_srv6_master[lchip]->fp_id_usp);
	SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_am_de_masq", p_usw_srv6_master[lchip]->fp_id_am_de_masq);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "udf_idx_base", p_usw_srv6_master[lchip]->udf_idx_base);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_shift", p_usw_srv6_master[lchip]->fp_id_shift);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_gsid_swap", p_usw_srv6_master[lchip]->fp_id_gsid_swap);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_gsid_pop", p_usw_srv6_master[lchip]->fp_id_gsid_pop);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "fp_id_gsid_psp", p_usw_srv6_master[lchip]->fp_id_gsid_psp);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "udf_idx_base", p_usw_srv6_master[lchip]->udf_idx_base);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "sid_format", p_usw_srv6_master[lchip]->sid_format);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "mask len(scl0)", p_usw_srv6_master[lchip]->masklen[0]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n", "mask len(scl1)", p_usw_srv6_master[lchip]->masklen[1]);

    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");
    SYS_SRV6_UNLOCK(lchip);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_srv6_wb_sync(uint8 lchip, uint32 app_id)
{
    int32 ret  = CTC_E_NONE;
    ctc_wb_data_t wb_data = {0};
    sys_wb_srv6_master_t* p_srv6_wb_master = NULL;

    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        return CTC_E_NONE;
    }

    SYS_USW_FTM_CHECK_NEED_SYNC(lchip);
    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);

    SYS_SRV6_LOCK(lchip);
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_SRV6_SUBID_MASTER)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_srv6_master_t, CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MASTER);
        p_srv6_wb_master = (sys_wb_srv6_master_t*)wb_data.buffer;

        p_srv6_wb_master->lchip = lchip;
        p_srv6_wb_master->version = SYS_WB_VERSION_SRV6;
        p_srv6_wb_master->fp_id_swap = p_usw_srv6_master[lchip]->fp_id_swap;
        p_srv6_wb_master->fp_id_psp = p_usw_srv6_master[lchip]->fp_id_psp;
        p_srv6_wb_master->fp_id_usp = p_usw_srv6_master[lchip]->fp_id_usp;
        p_srv6_wb_master->fp_id_shift = p_usw_srv6_master[lchip]->fp_id_shift;
		p_srv6_wb_master->fp_id_am_de_masq = p_usw_srv6_master[lchip]->fp_id_am_de_masq;
        p_srv6_wb_master->fp_id_gsid_swap = p_usw_srv6_master[lchip]->fp_id_gsid_swap;
        p_srv6_wb_master->fp_id_gsid_pop = p_usw_srv6_master[lchip]->fp_id_gsid_pop;
        p_srv6_wb_master->fp_id_gsid_psp = p_usw_srv6_master[lchip]->fp_id_gsid_psp;
        p_srv6_wb_master->udf_idx_base = p_usw_srv6_master[lchip]->udf_idx_base;
        p_srv6_wb_master->sid_format = p_usw_srv6_master[lchip]->sid_format;
        p_srv6_wb_master->masklen_scl0 = p_usw_srv6_master[lchip]->masklen[0];
        p_srv6_wb_master->masklen_scl1 = p_usw_srv6_master[lchip]->masklen[1];
        p_srv6_wb_master->ldp_base = p_usw_srv6_master[lchip]->ldp_base;

        wb_data.valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MASTER);
    }

    done:
    SYS_SRV6_UNLOCK(lchip);
    CTC_WB_FREE_BUFFER(wb_data.buffer);
    return ret;
}


STATIC int32
_sys_usw_srv6_wb_restore(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    ctc_wb_query_t wb_query;
    sys_wb_srv6_master_t srv6_wb_master;

    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);

    /*restore master*/
    /* set default value to new added fields, default value may not be zeros */
    sal_memset(&srv6_wb_master, 0, sizeof(sys_wb_srv6_master_t));

    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_srv6_master_t, CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MASTER);
    CTC_ERROR_GOTO(ctc_wb_query_entry(&wb_query), ret, done);
    if (wb_query.valid_cnt != 1 || wb_query.is_end != 1)
    {
        CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "query overlay master error! valid_cnt: %d, is_end: %d.\n", wb_query.valid_cnt, wb_query.is_end);
        ret = CTC_E_NONE;
        goto done;
    }

    sal_memcpy(&srv6_wb_master, wb_query.buffer, wb_query.key_len + wb_query.data_len);

    if (CTC_WB_VERSION_CHECK(SYS_WB_VERSION_SRV6, srv6_wb_master.version))
    {
        ret = CTC_E_VERSION_MISMATCH;
        goto done;
    }

    p_usw_srv6_master[lchip]->fp_id_swap = srv6_wb_master.fp_id_swap;
    p_usw_srv6_master[lchip]->fp_id_psp = srv6_wb_master.fp_id_psp;
    p_usw_srv6_master[lchip]->fp_id_usp = srv6_wb_master.fp_id_usp;
    p_usw_srv6_master[lchip]->fp_id_shift =  srv6_wb_master.fp_id_shift;
	p_usw_srv6_master[lchip]->fp_id_am_de_masq =  srv6_wb_master.fp_id_am_de_masq;
    p_usw_srv6_master[lchip]->fp_id_gsid_swap = srv6_wb_master.fp_id_gsid_swap;
    p_usw_srv6_master[lchip]->fp_id_gsid_pop = srv6_wb_master.fp_id_gsid_pop;
    p_usw_srv6_master[lchip]->fp_id_gsid_psp = srv6_wb_master.fp_id_gsid_psp;
    p_usw_srv6_master[lchip]->udf_idx_base = srv6_wb_master.udf_idx_base;
    p_usw_srv6_master[lchip]->sid_format = srv6_wb_master.sid_format;
    p_usw_srv6_master[lchip]->masklen[0] = srv6_wb_master.masklen_scl0;
    p_usw_srv6_master[lchip]->masklen[1] = srv6_wb_master.masklen_scl1;
    p_usw_srv6_master[lchip]->ldp_base = srv6_wb_master.ldp_base;
    if(DRV_FROM_AT(lchip))
    {
        sys_usw_nh_alloc_from_position(lchip, SYS_API_NH_LOGIC_DEST_PORT, SYS_AT_SRV6_EDIT_RSV_LPORT_NUM, p_usw_srv6_master[lchip]->ldp_base);
    }

 done:
    CTC_WB_FREE_BUFFER(wb_query.buffer);
     return ret;
}


int32
sys_usw_srv6_set_sid_format(uint8 lchip, ctc_srv6_global_cfg_t* p_global_cfg)
{
    SYS_SRV6_INIT_CHECK(lchip);
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_global_cfg);

    /* parameter check */
    if (p_global_cfg->sid_format_bmp >= 0x7)
    {
        return CTC_E_INVALID_PARAM;
    }

    /*deinit old*/
    _sys_usw_srv6_init_sredit(lchip, SRV6_DEINIT);
    _sys_usw_srv6_init_udf(lchip, SRV6_DEINIT);
    if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_GSID) && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        _sys_usw_srv6_init_gsid_scl_tcam(lchip, SRV6_DEINIT);
    }

    /*init new*/
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MASTER, 1);
    p_usw_srv6_master[lchip]->sid_format = p_global_cfg->sid_format_bmp;
    CTC_ERROR_RETURN(_sys_usw_srv6_init_sredit(lchip, SRV6_INIT));
    CTC_ERROR_RETURN(_sys_usw_srv6_init_udf(lchip, SRV6_INIT));
    if (CTC_FLAG_ISSET(p_global_cfg->sid_format_bmp, CTC_SRV6_SID_FORMAT_GSID) && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        CTC_ERROR_RETURN(_sys_usw_srv6_init_gsid_scl_tcam(lchip, SRV6_INIT));
    }
    CTC_ERROR_RETURN(_sys_usw_srv6_init_register(lchip));/* only for set IpeUserIdSrCtl.srUdfHitIndexBase */

    return CTC_E_NONE;
}

int32
sys_usw_srv6_show_status(uint8 lchip)
{
    uint8 i = 0;
    SYS_SRV6_INIT_CHECK(lchip);

    SYS_SRV6_LOCK(lchip);

    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "---------------SRv6 Status-----------------\n");
    if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_NORMAL))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid swap)        : %d\n", p_usw_srv6_master[lchip]->fp_id_swap);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid psp)         : %d\n", p_usw_srv6_master[lchip]->fp_id_psp);
		SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid am de-masq)  : %d\n", p_usw_srv6_master[lchip]->fp_id_am_de_masq);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid usp)         : %d\n", p_usw_srv6_master[lchip]->fp_id_usp);
        if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
        	for (i = 0; i <= SYS_SRV6_MAX_SID_NUM; i++)
            {
              SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "udf idx%d(sid)       : %d\n", i, (p_usw_srv6_master[lchip]->udf_idx_base + i));
            }
        }
    }
    else
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid swap)        : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid psp)         : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid am)          : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(sid usp)         : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "udf idx(sid)           : N/A\n");
    }

    if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_USID))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(usid shift)      : %d\n", p_usw_srv6_master[lchip]->fp_id_shift);
        if (!DRV_FROM_AT(lchip))
        {
            SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "udf idx(usid)       : %d\n",
                CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_NORMAL) ?
                (p_usw_srv6_master[lchip]->udf_idx_base + SYS_SRV6_MAX_SID_NUM + 1) : (p_usw_srv6_master[lchip]->udf_idx_base));
        }
    }
    else
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(usid shift)      : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "prefix len(usid)       : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "udf idx(usid)          : N/A\n");
    }

    if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_GSID))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(gsid swap)       : %d\n", p_usw_srv6_master[lchip]->fp_id_gsid_swap);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(gsid pop)        : %d\n", p_usw_srv6_master[lchip]->fp_id_gsid_pop);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(gsid psp)        : %d\n", p_usw_srv6_master[lchip]->fp_id_gsid_psp);
        if (!DRV_FROM_AT(lchip))
        {
            for (i = 0; i < 12; i++)
            {
              SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "udf idx%d(gsid)       : %d\n", i,
                CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_NORMAL) ?
                (p_usw_srv6_master[lchip]->udf_idx_base + SYS_SRV6_MAX_SID_NUM + 1 + i) : (p_usw_srv6_master[lchip]->udf_idx_base + i));
            }
        }
    }
    else
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(gsid swap)       : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(gsid pop)        : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "fp id(gsid psp)        : N/A\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "udf idx(gsid)          : N/A\n");
    }

    if (DRV_FROM_AT(lchip))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(base)          : %d\n", (p_usw_srv6_master[lchip]->ldp_base));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(sid swap)      : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_SID + SYS_AT_SRV6_EDIT_BMP_POP));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(sid psp)       : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_SID + SYS_AT_SRV6_EDIT_BMP_PSP));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(sid usp)       : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_SID + SYS_AT_SRV6_EDIT_BMP_USP));
		SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(sid am de-masq): %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_SID_AM_DE_MASQ + SYS_AT_SRV6_EDIT_BMP_POP));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(usid shift)    : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_USID + SYS_AT_SRV6_EDIT_BMP_SWAP));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(gsid swap)     : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_GSID + SYS_AT_SRV6_EDIT_BMP_SWAP));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(gsid pop)      : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_GSID + SYS_AT_SRV6_EDIT_BMP_POP));
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "ldp idx(gsid psp)      : %d\n", (p_usw_srv6_master[lchip]->ldp_base + SYS_AT_SRV6_EDIT_BASE_GSID + SYS_AT_SRV6_EDIT_BMP_PSP));
    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "mask len(scl0)   : %d\n", p_usw_srv6_master[lchip]->masklen[0]);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "mask len(scl1)   : %d\n", p_usw_srv6_master[lchip]->masklen[1]);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "---------------SRv6 default udf extract  -----------------\n");
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "acl sel-id0   : SRH offset %d\n", 0);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "acl sel-id1   : SRH offset %d\n", 2);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "acl sel-id2   : SRH offset %d\n", 4);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "acl sel-id3   : SRH offset %d\n", 6);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "scl sel-id0   : SRH offset %d\n", 2);
        SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "scl sel-id1   : SRH offset %d\n", 0);
    }

    SYS_SRV6_UNLOCK(lchip);
    return CTC_E_NONE;
}

int32
sys_usw_srv6_set_gsid_default_action(uint8 lchip, uint16 lport, uint8 deinit)
{
    sys_scl_default_action_t sys_default_action;
    ctc_scl_field_action_t field_action;

    SYS_SRV6_INIT_CHECK(lchip);
    sal_memset(&sys_default_action, 0, sizeof(sys_scl_default_action_t));
    sal_memset(&field_action, 0, sizeof(ctc_scl_field_action_t));

    /* set defualt entry */
    field_action.type = CTC_SCL_FIELD_ACTION_TYPE_PENDING;
    field_action.data0 = 1;
    sys_default_action.scl_id = 0;
    sys_default_action.lport = lport;
    sys_default_action.field_action = &field_action;
    CTC_ERROR_RETURN(sys_usw_scl_set_default_action(lchip, &sys_default_action));

    if (!deinit)
    {
        /* clear all scl result */
        field_action.type = CTC_SCL_FIELD_ACTION_TYPE_CANCEL_LKUP_BMP;
        field_action.data0 = 0x4;                       /* clear scl id 2 */
        field_action.data1 = 0;                         /* scl id */
        CTC_ERROR_RETURN(sys_usw_scl_set_default_action(lchip, &sys_default_action));
    }

    field_action.type = CTC_SCL_FIELD_ACTION_TYPE_PENDING;
    field_action.data0 = 0;
    CTC_ERROR_RETURN(sys_usw_scl_set_default_action(lchip, &sys_default_action));

    return CTC_E_NONE;
}

int32
sys_usw_srv6_init(uint8 lchip, ctc_srv6_global_cfg_t* p_global_cfg)
{
    int32 ret = CTC_E_NONE;
    uint8  work_status = 0;
    LCHIP_CHECK(lchip);

    if (NULL != p_usw_srv6_master[lchip])
    {
        return CTC_E_NONE;
    }
    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_srv6_master[lchip] = p_usw_srv6_master[drv_vchip_get_pp_base(lchip)];
        return CTC_E_NONE;
    }
    
    if (NULL== p_global_cfg )
    {
        return CTC_E_INVALID_PARAM;
    }
    /* parameter check */
    if (p_global_cfg->sid_format_bmp >= 0x7)
    {
        return CTC_E_INVALID_PARAM;
    }

    sys_usw_ftm_get_working_status(lchip, &work_status);
    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING && (3 == work_status))
    {
        drv_set_warmboot_status(lchip, CTC_WB_STATUS_DONE);
    }

    if (NULL == p_usw_srv6_master[lchip])
    {
        p_usw_srv6_master[lchip] = mem_malloc(MEM_SRV6_MODULE, sizeof(sys_srv6_master_t));
        if (!p_usw_srv6_master[lchip])
        {
            SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
            return CTC_E_NO_MEMORY;
        }
        sal_memset(p_usw_srv6_master[lchip], 0, sizeof(sys_srv6_master_t));
    }

    if (!(CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING))
    {
        CTC_ERROR_GOTO(sys_usw_srv6_set_global_cfg(lchip, p_global_cfg, 0, 0), ret, error_proc);  /* Init mask registers */
        CTC_ERROR_GOTO(_sys_usw_srv6_init_sredit(lchip, SRV6_INIT), ret, error_proc);
        CTC_ERROR_GOTO(_sys_usw_srv6_init_udf(lchip, SRV6_INIT), ret, error_proc);   /* TMM */
        CTC_ERROR_GOTO(_sys_usw_srv6_init_scl(lchip, SRV6_INIT), ret, error_proc);
        if (CTC_FLAG_ISSET(p_usw_srv6_master[lchip]->sid_format, CTC_SRV6_SID_FORMAT_GSID) && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))) /* TMM */
        {
            CTC_ERROR_GOTO(_sys_usw_srv6_init_gsid_scl_tcam(lchip, SRV6_INIT), ret, error_proc);
        }
        CTC_ERROR_GOTO(_sys_usw_srv6_init_register(lchip), ret, error_proc);
        /*Enable auxEditData XPH*/ /* for arctic */
        if (MCHIP_XDATA(lchip)->func_en && !SYS_VCHIP_PP_IS_NOT_BASE(lchip))
        {
            CTC_ERROR_GOTO(MCHIP_XDATA(lchip)->func_en(lchip, SYS_XDATA_FUNC_LOGIC_PORT_EXT, 1, NULL), ret, error_proc);
        }
    }



    sal_mutex_create(&p_usw_srv6_master[lchip]->mutex);
    if (NULL == p_usw_srv6_master[lchip]->mutex)
    {
        return CTC_E_NO_MEMORY;
    }

    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SRV6, SYS_WB_APPID_SRV6_SUBID_MAX,_sys_usw_srv6_wb_sync), ret, error_proc);
    if ( CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(_sys_usw_srv6_wb_restore(lchip), ret, error_proc);
    }
    if (CTC_WB_ENABLE(lchip))
    {
        _sys_usw_srv6_wb_init(lchip);
    }

    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_SRV6, _sys_usw_srv6_dump_db), ret, error_proc);
    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_SRV6);
    return CTC_E_NONE;
error_proc:
    if (p_usw_srv6_master[lchip]->mutex)
    {
        sal_mutex_destroy(p_usw_srv6_master[lchip]->mutex);
    }
    mem_free(p_usw_srv6_master[lchip]);
    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING && (3 == work_status))
    {
        drv_set_warmboot_status(lchip, CTC_WB_STATUS_RELOADING);
    }
    return ret;
}
int32
sys_usw_srv6_deinit(uint8 lchip)
{
    LCHIP_CHECK(lchip);

    if (NULL == p_usw_srv6_master[lchip])
    {
        return CTC_E_NONE;
    }
    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_srv6_master[lchip] = NULL;
        return CTC_E_NONE;
    }
    sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_SRV6,0, NULL);
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_SRV6, NULL);

    sal_mutex_destroy(p_usw_srv6_master[lchip]->mutex);
    mem_free(p_usw_srv6_master[lchip]);
    p_usw_srv6_master[lchip] = NULL;
    return CTC_E_NONE;
}

int32
sys_usw_srv6_add_my_sid(uint8 lchip, ctc_srv6_sid_t* my_sid)
{
    ctc_scl_entry_t  scl_entry;
    uint32 group_id = 0;
    int32 ret = CTC_E_NONE;

    SYS_SRV6_INIT_CHECK(lchip);
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(my_sid);

    CTC_ERROR_RETURN(_sys_usw_srv6_param_check(lchip, my_sid));
    sal_memset(&scl_entry, 0, sizeof(ctc_scl_entry_t));

    SYS_SRV6_LOCK(lchip);
    /* add scl entry */
    group_id = SYS_SCL_ENCODE_INNER_GRP_ID(CTC_FEATURE_SRV6, my_sid->scl_id, 0, 0, 0);
    scl_entry.action_type = SYS_SCL_ACTION_INGRESS;
    scl_entry.mode = 1;
    scl_entry.key_type = _sys_usw_srv6_mapping_scl_key_type(lchip, my_sid);
    scl_entry.entry_id = my_sid->scl_entry_id;
    CTC_ERROR_GOTO(sys_usw_scl_add_entry(lchip, group_id, &scl_entry, 1), ret, error_proc);
    /* build key */
    CTC_ERROR_GOTO(_sys_usw_srv6_build_key(lchip, scl_entry.entry_id, scl_entry.key_type, my_sid), ret, error_proc);
    /* build action */
    CTC_ERROR_GOTO(_sys_usw_srv6_build_action(lchip, scl_entry.entry_id, my_sid, 0), ret, error_proc);
    /* install entry */
    CTC_ERROR_GOTO(sys_usw_scl_install_entry(lchip, scl_entry.entry_id, 1), ret, error_proc);
    my_sid->scl_entry_id = scl_entry.entry_id;
    SYS_SRV6_UNLOCK(lchip);
    return CTC_E_NONE;
error_proc:
    sys_usw_scl_remove_entry(lchip, scl_entry.entry_id, 1);
    SYS_SRV6_UNLOCK(lchip);
    return ret;
}
int32
sys_usw_srv6_remove_my_sid(uint8 lchip, ctc_srv6_sid_t* my_sid)
{
    sys_scl_lkup_key_t lkup_key;
	sys_scl_srv6_t srv6;
	ctc_scl_field_action_t field_action;
    int32 ret = CTC_E_NONE;

    SYS_SRV6_INIT_CHECK(lchip);
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(my_sid);

    sal_memset(&lkup_key, 0, sizeof(sys_scl_lkup_key_t));
	sal_memset(&field_action, 0, sizeof(ctc_scl_field_action_t));
    sal_memset(&srv6, 0, sizeof(sys_scl_srv6_t));

    SYS_SRV6_LOCK(lchip);
    CTC_ERROR_GOTO(_sys_usw_srv6_construct_key(lchip, my_sid, &lkup_key), ret, error_proc);

	field_action.type = SYS_SCL_FIELD_ACTION_TYPE_SRV6;
    field_action.ext_data = &srv6;
    CTC_ERROR_GOTO(sys_usw_scl_get_action_field(lchip, lkup_key.entry_id, &field_action), ret, error_proc);
	if (srv6.router_mac_profile)
	{
		CTC_ERROR_GOTO(sys_usw_l3if_unbinding_inner_router_mac(lchip, srv6.router_mac_profile), ret, error_proc);
	}

    CTC_ERROR_GOTO(sys_usw_scl_uninstall_entry(lchip, lkup_key.entry_id, 1), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_scl_remove_entry(lchip, lkup_key.entry_id, 1), ret, error_proc);
    my_sid->scl_entry_id = lkup_key.entry_id;
    SYS_SRV6_UNLOCK(lchip);
    return CTC_E_NONE;
error_proc:
    SYS_SRV6_UNLOCK(lchip);
    return ret;
}
int32
sys_usw_srv6_update_my_sid(uint8 lchip, ctc_srv6_sid_t* my_sid)
{
    sys_scl_lkup_key_t lkup_key;
    int32 ret = CTC_E_NONE;
    SYS_SRV6_INIT_CHECK(lchip);
    SYS_SRV6_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(my_sid);
    CTC_ERROR_RETURN(_sys_usw_srv6_param_check(lchip, my_sid));

    sal_memset(&lkup_key, 0, sizeof(sys_scl_lkup_key_t));

    SYS_SRV6_LOCK(lchip);
    CTC_ERROR_GOTO(_sys_usw_srv6_construct_key(lchip, my_sid, &lkup_key), ret, error_proc);
    CTC_ERROR_GOTO(_sys_usw_srv6_build_action(lchip, lkup_key.entry_id, my_sid, 1), ret, error_proc);
    CTC_ERROR_GOTO(sys_usw_scl_install_entry(lchip, lkup_key.entry_id, 1), ret, error_proc);

    SYS_SRV6_UNLOCK(lchip);
    return CTC_E_NONE;
error_proc:
    SYS_SRV6_UNLOCK(lchip);
    return ret;
}

#endif


